/*
 * Copyright (C) 2011  John Lawrence thegordo.john at gmail.com
 * Licensed under GPLv3 or later. see http://www.gnu.org/copyleft/gpl.html
 */

package org.jklawrencefam.server.smtp;

import org.jklawrencefam.Util.LogFactory;
import org.jklawrencefam.server.Processor;

import java.net.InetAddress;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * User: John Lawrence
 * Date: 5/17/11
 * Time: 9:14 PM
 */
public class SmtpProcessor extends Processor {
    private Logger logger = LogFactory.getLogger(SmtpProcessor.class);

    @Override
    public void run() {
        try {
            InetAddress address = socket.getInetAddress();
            logger.fine("I'm accepting a connection! " + address.getHostAddress());
            SmtpProtocol protocol = new SmtpProtocol();
            out.println(protocol.getInitialMessage());
            logger.finest("Wrote initial message!");
            //noinspection InfiniteLoopStatement
            while (true) {
                // TODO: There needs to be some sort of timeout occurring here.
                String command = incoming.nextLine();
                logger.finest("Received: " + command);
                protocol.processCommand(command);
                out.println(protocol.getNextMessage());
                switch (protocol.getActionState()) {
                    case QUIT:
                        throw new SMTPException();
                    case PROLONGED_READ:
                        String line;
                        StringBuilder messageBody = new StringBuilder();
                        do {
                            line = incoming.nextLine();
                            messageBody.append(line).append("\n");
                        } while (!line.equals("."));
                        protocol.setMessageBody(messageBody.toString());
                        out.println(protocol.getNextMessage());
                        logger.fine("Received Message: \n" + messageBody);
                        break;
                    case NONE:
                    default:
                        // Do nothing.
                }
            }
        } catch (SMTPException e) {
            logger.fine("leaving the connection");
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Error communicating with client", e);
        } finally {
            closeConnections();
        }
    }

    private class SMTPException extends RuntimeException {
    }
}
